/**********************************************
	* @author: Jun
	* @time  : 2018/8/1
	* @brief ：像素点操作
	* @note  ：none
**********************************************/
#include "oc_pixel.h"

/**********************************************
	* @brief  : 使用 Bresenham 算法画线段（基于两点） 
	* @param  : xpos1 ：线段的一个端点X坐标
	* @param  : ypos1 ：线段的一个端点Y坐标
	* @param  : xpos2 ：线段的另一个端点X坐标
	* @param  : ypos2 ：线段的另一个端点Y坐标
	* @note  
	* @retval : 无
**********************************************/
void oc_draw_line ( uint16_t xpos1, uint16_t ypos1, uint16_t xpos2, uint16_t ypos2 )
{
	uint16_t us; 
	uint16_t usX_Current, usY_Current;
	
	int32_t lError_X = 0, lError_Y = 0, lDelta_X, lDelta_Y, lDistance; 
	int32_t lIncrease_X, lIncrease_Y; 	
	
	
	lDelta_X = xpos2 - xpos1; //计算坐标增量 
	lDelta_Y = ypos2 - ypos1; 
	
	usX_Current = xpos1; 
	usY_Current = ypos1; 
	
	
	if ( lDelta_X > 0 ) 
		lIncrease_X = 1; //设置单步方向 
	else if ( lDelta_X == 0 ) 
		lIncrease_X = 0;//垂直线 
	else 
  { 
    lIncrease_X = -1;
    lDelta_X = - lDelta_X;
  } 

	
	if ( lDelta_Y > 0 )
		lIncrease_Y = 1; 
	else if ( lDelta_Y == 0 )
		lIncrease_Y = 0;//水平线 
	else 
  {
    lIncrease_Y = -1;
    lDelta_Y = - lDelta_Y;
  } 

	
	if (  lDelta_X > lDelta_Y )
		lDistance = lDelta_X; //选取基本增量坐标轴 
	else 
		lDistance = lDelta_Y; 

	for ( us = 0; us <= lDistance + 1; us ++ )//画线输出 
	{  
		oc_base_dot( usX_Current, usY_Current );//画点 
		
		lError_X += lDelta_X ; 
		lError_Y += lDelta_Y ; 
		
		if ( lError_X > lDistance ) 
		{ 
			lError_X -= lDistance; 
			usX_Current += lIncrease_X; 
		}  
		
		if ( lError_Y > lDistance ) 
		{ 
			lError_Y -= lDistance; 
			usY_Current += lIncrease_Y; 
		} 
	}  	
}   

/**********************************************
	* @brief  :绘制空心矩形
	* @param  :xpos ：矩形左上角端点X坐标
	* @param  :ypos ：矩形左上角端点Y坐标
	* @param  :wpos ：矩形宽
	* @param  :height ：矩形高
	* @note :
	* @retval :无
**********************************************/
void oc_draw_rect(uint16_t xpos, uint16_t ypos, uint16_t wpos, uint16_t height)
{  
  oc_draw_line(xpos, ypos, xpos+wpos, ypos);
  oc_draw_line(xpos, ypos, xpos, ypos+height);
  oc_draw_line(xpos+wpos, ypos, xpos+wpos, ypos+height);
  oc_draw_line(xpos, ypos + height, xpos+wpos, ypos+height);
}

/**********************************************
	* @brief  :绘制实心矩形
	* @param  :xpos ：矩形左上角端点X坐标
	* @param  :ypos ：矩形左上角端点Y坐标
	* @param  :wpos ：矩形宽
	* @param  :height ：矩形高
	* @note :
	* @retval :无
**********************************************/
void oc_draw_full_rect(uint16_t xpos, uint16_t ypos, uint16_t wpos, uint16_t height)
{  
	oc_draw_line(xpos, ypos, xpos+wpos, ypos);
	oc_draw_line(xpos, ypos, xpos, ypos+height);
	oc_draw_line(xpos+wpos, ypos, xpos+wpos, ypos+height);
	oc_draw_line(xpos, ypos + height, xpos+wpos, ypos+height);
	
	for(uint16_t i = 0;i < height;i++)
	{
		oc_draw_line(xpos, ypos + i, xpos+wpos, ypos + i);
	}
}

/**********************************************
	* @brief  :绘制空心圆
	* @param  :xpos ：中心点X坐标
	* @param  :ypos ：中心点Y坐标
	* @param  :Radius ：圆形半径
	* @note :
	* @retval :无
**********************************************/
void oc_draw_circle(uint16_t xpos,uint16_t ypos,uint16_t Radius)
{
	int16_t mx=xpos,my=ypos,x=0,y=Radius;
	int16_t d=1-Radius;
	while(y>x)
	{
		oc_base_dot(x+mx,y+my);
		oc_base_dot(-x+mx,y+my);
		oc_base_dot(-x+mx,-y+my);
		oc_base_dot(x+mx,-y+my);
		oc_base_dot(y+mx,x+my);
		oc_base_dot(-y+mx,x+my);
		oc_base_dot(y+mx,-x+my);
		oc_base_dot(-y+mx,-x+my);
		
		if(d<0)
		{
			d += 2*x+3;
		}
		else
		{
			d += 2*(x-y)+5;
			y--;
		}
		x++;
	}
}

/**********************************************
	* @brief  : 使用 Bresenham 算法画椭圆
	* @param  : xpos ：线段的一个端点X坐标
	* @param  : ypos ：线段的一个端点Y坐标
	* @param  : xRadius ：线段的另一个端点X坐标
	* @param  : yRadius ：线段的另一个端点Y坐标
	* @note  
	* @retval : 无
**********************************************/
void oc_draw_ellipse ( int xpos, int ypos,int xRadius, int yRadius)
{
	int x,y;
	float d1,d2;
	x = 0;y = yRadius;
	d1=yRadius*yRadius+xRadius*xRadius*(-yRadius+0.25);

	oc_base_dot(xpos+x,ypos+y);
	oc_base_dot(xpos-x,ypos-y);
	oc_base_dot(xpos-x,ypos+y);
	oc_base_dot(xpos+x,ypos-y);
	
	while(yRadius*yRadius*(x+1) < xRadius*xRadius*(y-0.5))
	{
		if(d1<=0)
		{
			d1+=yRadius*yRadius*(2*x+3);
			x++;
		}
		else
		{
			d1+=yRadius*yRadius*(2*x+3)+xRadius*xRadius*(-2*y+2);
			x++;
			y--;
		}
		oc_base_dot(xpos+x,ypos+y);
		oc_base_dot(xpos-x,ypos-y);
		oc_base_dot(xpos-x,ypos+y);
		oc_base_dot(xpos+x,ypos-y);
  }//while上半部分
  d2=yRadius*yRadius*(x+0.5)*(x+0.5)+xRadius*xRadius*(y-1)*(y-1)-xRadius*xRadius*yRadius*yRadius;
	while(y>0)
	{
		if(d2<=0)
		{
			d2+=yRadius*yRadius*(2*x+2)+xRadius*xRadius*(-2*y+3);
			x++,y--;
		}
		else
		{
			d2+=xRadius*xRadius*(-2*y+3);
			y--;
		}
		oc_base_dot(xpos+x,ypos+y);
		oc_base_dot(xpos-x,ypos-y);
		oc_base_dot(xpos-x,ypos+y);
		oc_base_dot(xpos+x,ypos-y);
  }
}

